package com.common.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import com.alibaba.fastjson.JSON;

/**
 * @description:Bean工具类
 * @author 发动机
 */
public class BeanUtilsExtends extends BeanUtils {
	
    static {
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        ConvertUtils.register(new DateConvert(), java.sql.Date.class);
    }

    /**
     * @description:从一个orig中复制相同属性的值到另外一个dest中
     * @author 发动机
     * @param dest 目标对象
     * @param orig 源对象
     */
    public static void copyProperties(Object dest, Object orig) {
        try {
            BeanUtils.copyProperties(dest, orig);
        } catch (IllegalAccessException ex) {
            System.err.println("dest：" + JSON.toJSONString(dest));
            System.err.println("orig：" + JSON.toJSONString(orig));
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            System.err.println("dest：" + JSON.toJSONString(dest));
            System.err.println("orig：" + JSON.toJSONString(orig));
            ex.printStackTrace();
        }
    }
    
    /**    
     * @description:Map<String, Object> --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean
     * @author 发动机
     * @param map
     * @param obj 
    */
    public static void transMap2Bean2(Map<String, Object> map, Object obj) {
        if (map == null || obj == null) {
            return;
        }
        try {
            BeanUtils.populate(obj, map);
        } catch (Exception e) {
            System.out.println("transMap2Bean2 Error " + e);
        }
    }

    /**    
     * @description:Map<String, Object> --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
     * @author 发动机
     * @param map
     * @param obj 
    */
    public static void transMap2Bean(Map<String, Object> map, Object obj) {

        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                if (map.containsKey(key)) {
                    Object value = map.get(key);
                    // 得到property对应的setter方法
                    Method setter = property.getWriteMethod();
                    setter.invoke(obj, value);
                }

            }

        } catch (Exception e) {
            System.out.println("transMap2Bean Error " + e);
        }

        return;

    }

    /**    
     * @description:Bean --> Map<String, Object> 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
     * @author 发动机
     * @param obj
     * @return 
    */
    public static Map<String, Object> transBean2Map(Object obj) {

        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);

                    map.put(key, value);
                }

            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }

        return map;

    }
    
    /**    
     * @description:Bean --> Map<String, String> 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
     * @author 发动机
     * @param obj
     * @return 
    */
    public static Map<String, String> transBean2MapStr(Object obj) {

        if (obj == null) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    if(null != value) {
                        if(value instanceof Date) {
                            value = DateUtils.getStrDate((Date) value);
                        } else if (value instanceof String) {
                            value = (String) value;
                        } else if (value instanceof Object) {
                            value = JSON.toJSONString(value);
                        }
                        map.put(key, value + "");
                    }
                }

            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }

        return map;

    }
    
    /**    
     * @description:Map<String, String> --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
     * @author 发动机
     * @param map
     * @param obj 
    */
    public static void transMapStr2Bean(Map<String, String> map, Object obj) {

        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                if (map.containsKey(key)) {
                    Object value = map.get(key);
                    // 得到property对应的setter方法
                    Method setter = property.getWriteMethod();
                    if (value.equals("null")) {
                        value = null;
                    } else if (setter.getParameterTypes()[0].equals(Date.class)) {
                        value = new DateConvert().convert(Date.class, value);
                    } else if (setter.getParameterTypes()[0].equals(Integer.class)) {
                        value = Integer.parseInt(value + "");
                    } else if (setter.getParameterTypes()[0].equals(Long.class)) {
                        value = Long.parseLong(value + "");
                    } else if (setter.getParameterTypes()[0].equals(Double.class)) {
                        value = Double.parseDouble(value + "");
                    } else if (setter.getParameterTypes()[0].equals(Float.class)) {
                        value = Float.parseFloat(value + "");
                    } else if (setter.getParameterTypes()[0].equals(Boolean.class)) {
                        value = Boolean.parseBoolean(value + "");
                    } else if (setter.getParameterTypes()[0].equals(BigDecimal.class)) {
                        value = new BigDecimal(value + "");
                    } else if (setter.getParameterTypes()[0].equals(String.class)) {
                        value = value + "";
                    } else if (setter.getParameterTypes()[0].equals(List.class)) {
                        value = JSON.parseArray(value + "", setter.getParameterTypes()[0]);
                    } else {
                        value = JSON.parseObject(value + "", setter.getParameterTypes()[0]);
                    }
                    setter.invoke(obj, value);
                }
            }
        } catch (Exception e) {
            System.out.println("transMap2Bean Error " + e);
        }

        return;

    }
}
